import java.util.*;

class State{
	
	private StateType type = StateType.END;
	public int subtype = -1;
	
	public State(){}
	
	public State(StateType st){
		type = st;
	}
	public StateType getType(){
		return type;
	}
	
	public void setType(StateType t){
		type = t;
	}
	public State nextState(char i){
		return null;
	}
}

enum StateType {
	END, IDENT, ELSE, IF, WHILE, BREAK, PRINT, STR,
    INTEGER_TYPE, FLOAT_TYPE, INTEGER, FLOAT,  
    PLUS, MINUS, MULTIPLY, DIVIDE, ASSIGN, LT, LE, EQ, NE, GT, GE, MOD,
    PLUS_A, MINUS_A, MULTIPLY_A, DIVIDE_A,
    AND, OR, NOT,  
    COMMA, SEMI, LPARENT, RPARENT, LBRACKET, RBRACKET, LBRACE, RBRACE, GET_ATTR,COLON,
    SPACE, DENY  ,SKIP
}

public final class StateMactine {
	
	private static State start, deny, strSt, intSt, spaceSt, identSt, floatSt ;
	StateMactine(){
		start = new State(){
			public State nextState(char i){
				if(isAlpha(i) || i == '_'){
					return identSt;
				}else if(isDigit(i)){
					if(i == '0'){
						intSt.subtype = 8160;
					}else{
						intSt.subtype = 10;
					}
					return intSt;
				}else if(i == '\"'){
					return strSt;
				}else if(isSpace(i)){
					return spaceSt;
				}else {
					return smap.get(String.valueOf(i));
				}
			}
		};
		current = start;
		deny = new State(StateType.DENY);
		intSt = new State(StateType.INTEGER){
			public State nextState(char i){
				if(intSt.subtype == 10){
					if(isDigit(i)){
						return intSt;
					}else if(i == '.'){
						intSt.subtype = -1;
						return floatSt;
					}else if(isAlpha(i)){
						intSt.subtype = -1;
						return deny;
					}
				}else if(intSt.subtype == 8){
					if(i< '8' && i >='0'){
						return intSt;
					}else if(i == '.'){
						intSt.subtype = -1;
						return floatSt;
					}else if(isAlpha(i) || i == '9' || i == '8'){
						intSt.subtype = -1;
						return deny;
					}
				}else if(intSt.subtype == 16){
					if((i<= '9' && i >='0') || (i >= 'a' && i<= 'f') || (i >= 'A' && i<= 'F')){
						return intSt;
					}else{
						intSt.subtype = -1;
						return null;
					}										
				}else if(intSt.subtype == 8160){
					if(i=='x' || i=='X'){
						intSt.subtype = 16;
						return intSt;
					}else if(i > '0' && i < '8'){
						intSt.subtype = 8;
						return intSt;
					}else if(i == '.'){
						intSt.subtype = -1;
						return floatSt;
					}else{
						intSt.subtype = -1;
						return null;
					}
				}
				intSt.subtype = -1;
				return null;
			}
		};
		strSt = new State(StateType.STR){
			public State nextState(char i){
				if( strSt.subtype == -1){
					strSt.subtype = 1;
				}else if(strSt.subtype == 1){
					if(i == '\"'){
						strSt.subtype = 2;
					}else if(i == '\n' || i== '\r'){
						return deny;
					}
				}else if(strSt.subtype == 2){
					strSt.subtype = -1;
					return null;
				}
				return this;
			}
		};
		floatSt = new State(StateType.FLOAT){
			public State nextState(char i){
				if(isDigit(i)){
					return floatSt;
				}else if(i == '.' || isAlpha(i)){
					return deny;
				}else{
					return null;
				}
			}
		};
		identSt = new State(StateType.IDENT){
			public State nextState(char i){
				if(isDigit(i) || isAlpha(i) || i=='_' ){
					return identSt;
				}
				return null;
			}
		};
		spaceSt = new State(StateType.SPACE){
			public State nextState(char i){
				if(isSpace(i)){
					return spaceSt;
				}else{
					return null;
				}
			}
		};
	}
	private static Map<String, State> smap = new HashMap<String, State>();
	static {
			smap.put("(", new State(StateType.LPARENT));
			smap.put(")", new State(StateType.RPARENT));
			smap.put("[", new State(StateType.LBRACKET));
			smap.put("]", new State(StateType.RBRACKET));
			smap.put("{", new State(StateType.LBRACE));
			smap.put("}", new State(StateType.RBRACE));
			smap.put("+", new State(StateType.PLUS){
						public State nextState(char i){
							if(i=='='){
								return new State(StateType.PLUS_A);
							}else if(i=='+'){
								return deny;
							}
							return null;
						}
				});
			smap.put("-", new State(StateType.MINUS){
						public State nextState(char i){
							if(i=='='){
								return new State(StateType.MINUS_A);
							}else if(i=='-'){
								return deny;
							}
							return null;
						}				
				});
			smap.put("*", new State(StateType.MULTIPLY){
						public State nextState(char i){
							if(i=='='){
								return new State(StateType.MULTIPLY_A);
							}else if(i=='*'){
								return deny;
							}
							return null;
						}					
				});
			smap.put("/", new State(StateType.DIVIDE){
						public State nextState(char i){
							if(i=='='){
								return new State(StateType.DIVIDE_A);
							}else if(i=='/'){
								return new State(StateType.SKIP){
									public State nextState(char c){
										if(c=='\n') return null;
										return this;
									}
								};
							}
							return null;
						}					
				});
			smap.put("!", new State(StateType.NOT){
						public State nextState(char i){
							if(i=='='){
								return new State(StateType.NE);
							}
							return null;
						}					
				});
			smap.put("&", new State(StateType.AND));
			smap.put("|", new State(StateType.OR));
			smap.put("=", new State(StateType.ASSIGN){
						public State nextState(char i){
							if(i=='='){
								return new State(StateType.EQ);
							}
							return null;
						}					
				});
			smap.put(">", new State(StateType.GT){
						public State nextState(char i){
							if(i=='='){
								return new State(StateType.GE);
							}
							return null;
						}					
				});
			
			smap.put("<", new State(StateType.LT){
						public State nextState(char i){
							if(i=='='){
								return new State(StateType.LE);
							}
							return null;
						}					
				});
			smap.put(";", new State(StateType.SEMI));
			smap.put(",", new State(StateType.COMMA));
			smap.put(".", new State(StateType.GET_ATTR));
			smap.put(":", new State(StateType.COLON));
			smap.put("%", new State(StateType.MOD));
	}

	public static boolean isAlpha(char i){
		return (i>='a' &&  i<='z') || (i>='A' && i<='Z');
		}
		
	public static boolean isDigit(char i){
		return (i>='0' &&  i<='9') ;
		}
		
	public static boolean isSpace(char i){
		return (i==' ' || i=='\r' || i=='\n' || i=='\t') ;
		}
		
	private State current = null;
		
	public State nextState(char c){
		current = current.nextState(c);
		if (current==null){
			current = start;
			return null;
		}
		return current;
	}	

	/**
	 * Method main
	 *
	 *
	 * @param args
	 *
	 */
	public static void main(String[] args) {

	}	
}
